# -*- coding: UTF-8 -*-
import threading

from django.http import JsonResponse, HttpResponse
from django.utils.decorators import method_decorator
from django.views import View
from tinyapp.models import Templates, Users
from tinyapp.model.style_API import train_new_style, transfer_img
from django.core import serializers
import requests
import json
import uuid
from TinyAppContest.settings import MODEL_PREFIX, PIC_PREFIX
from weixin import WXAPPAPI
from weixin.lib.wxcrypt import WXBizDataCrypt
import os
from django.views.decorators.csrf import csrf_exempt

APP_ID = "wx3a12903f8cf05419"
APP_SECRET = "373f87d7d5c016f2a73516369f271d40"
api = WXAPPAPI(appid=APP_ID,
               app_secret=APP_SECRET)


# Create your views here.

@method_decorator(csrf_exempt, name='dispatch')
class LoginView(View):
    def get(self, request):
        code = request.GET['code']

        # print(code)

        session_info = api.exchange_code_for_session_key(code=code)
        session_key = session_info.get('session_key')
        return HttpResponse(session_key)

    def post(self, request):

        # print(request.POST['ed'])
        data = json.loads(request.body)
        ed = data['ed']
        iv = data['iv']
        session_key = data['session_key']
        # print('ed',ed,'\niv',iv,'\nkey',session_key)
        crypt = WXBizDataCrypt(APP_ID, session_key)
        # encrypted_data 包括敏感数据在内的完整用户信息的加密数据
        # iv 加密算法的初始向量
        # 这两个参数需要js获取
        user_info = crypt.decrypt(ed, iv)
        openid = user_info['openid']
        if Users.objects.filter(openid=openid).exists():
            return JsonResponse({'openid': openid})
        else:
            Users.objects.create(openid=openid, img_remain=30, template_remain=10)
            return JsonResponse({'openid': openid})


class TemplateListView(View):
    def get(self, request):
        data = Templates.objects.filter(is_public=1)
        data = serializers.serialize("json", data)
        return HttpResponse(data, content_type='application/json')


class UserTemplateListView(View):
    def get(self, request):
        openid = request.GET['userID']
        data = Templates.objects.filter(user_openid=openid)
        data = serializers.serialize("json", data)
        return HttpResponse(data, content_type='application/json')


@method_decorator(csrf_exempt, name='dispatch')
class TransferView(View):
    def post(self, request):
        openid = request.POST['userID']
        template_id = request.POST['templateID']
        user_img_file = request.FILES["img"]
        if user_img_file:
            user_img_path = os.path.join(PIC_PREFIX, user_img_file.name)
            destination = open(user_img_path, 'wb+')
            for chunk in user_img_file.chunks():
                destination.write(chunk)
            destination.close()
        model_path = Templates.objects.filter(pk=template_id).first().model_path
        model_path = os.path.join(MODEL_PREFIX, model_path)
        if Users.objects.get(openid=openid).img_remain > 0:
            k = Users.objects.get(openid=openid).img_remain
            Users.objects.filter(openid=openid).update(img_remain=k - 1)
            # transfer
            # return : img
            trans_img_path = os.path.join(PIC_PREFIX, uuid.uuid1().hex + ".png")
            transfer_img(user_img_path, model_path, trans_img_path)
            headers = {'Authorization': 'F80ylLk5Nn6QBpF9xpT2r0UFKSfF8rVC'}
            files = {'smfile': open(trans_img_path, 'rb')}
            url = 'https://sm.ms/api/v2/upload'
            res = requests.post(url, files=files, headers=headers).json()
            if res['success']:
                return HttpResponse(res['data']['url'])
            elif res['code'] == 'image_repeated':
                return HttpResponse(res['images'])
            else:
                return HttpResponse("")
        else:
            return HttpResponse("")


@method_decorator(csrf_exempt, name='dispatch')
class TrainView(View):
    def post(self, request):
        template_name = request.POST['templateName']
        user_nickname = request.POST['userName']
        openid = request.POST['userID']
        desc = request.POST['templateDesc']
        pic_path = request.FILES['picPath']
        train_img_path = os.path.join(PIC_PREFIX, pic_path.name)
        destination = open(train_img_path, 'wb+')
        for chunk in pic_path.chunks():
            destination.write(chunk)
        destination.close()
        headers = {'Authorization': 'F80ylLk5Nn6QBpF9xpT2r0UFKSfF8rVC'}
        files = {'smfile': open(train_img_path, 'rb')}
        url = 'https://sm.ms/api/v2/upload'
        res = requests.post(url, files=files, headers=headers).json()
        if Users.objects.get(openid=openid).template_remain > 0:
            r = Users.objects.get(openid=openid).template_remain - 1
            Users.objects.filter(openid=openid).update(template_remain=r)
            model_path = os.path.join(MODEL_PREFIX, template_name + ".pth")
            t = Templates()
            t.name = template_name
            t.model_path = model_path
            if res['success']:
                t.pic_path = res['data']['url']
            else:
                t.pic_path = res['images']
            t.desc = desc
            t.user_nickname = user_nickname
            t.user_openid = openid
            t.is_available = False
            t.is_public = False
            t.save()
            train_task = threading.Thread(target=train_thread, args=(train_img_path, model_path))
            train_task.start()
            return HttpResponse("True")
        else:
            return HttpResponse("False")


def train_thread(train_img_path, model_path):
    train_new_style(train_img_path, model_path)
    Templates.objects.filter(model_path=model_path).update(is_available=True)
